﻿/* =====================================================================================================
* FileName: PrintHelper            
* Created By: 马志
* Created Date: 2015年12月17日
* Email：hautmz@163.com
* Modified By:
* Modified Date:
* Copyright (c) 2010 - 2015 北京其乐融融科技有限公司
* ===================================================================================================== */

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using QlrrPrintService.Print;
using QlrrPrintService.Common;
using Newtonsoft.Json;
using System.IO;
using Newtonsoft.Json.Linq;
using System.Threading;
using PluginBase;
using PluginBase.Sockets;

namespace QlrrPrintService
{

    sealed class Options
    {
        public string hive = "HKCU";
        public string manifest =
            Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location) + "\\" + "QlrrPrintService.manifest.json";
    }

    public class ServiceHelper:IDisposable
    {
        #region 变量

        protected AsyncSocketServer<PluginRequestMessage> _socketServer = new AsyncSocketServer<PluginRequestMessage>(6000, 10);

        private static Options options = new Options();

        private string _extensionid = "halmbimoannfadoedalghfeihhjblaaj";

        #endregion

        #region 构造函数

        public ServiceHelper() {
            _socketServer.OnReceivedMessage += new HandleMessageHandler<PluginRequestMessage>(HandOnReceivedSocketMessage);
            _socketServer.OnConnectedServer += new SocketConnectedHandler<PluginRequestMessage>(HandOnConnectedServer);
            PrintManager.Instance.OnExquteComplete += new OnCommandExquteCompleteHander(CommandCompleteHander);
        }

       

        #endregion

        #region 受保护方法

        protected virtual void HandMessage(PluginRequestMessage msg)
        {
            if (msg != null)
            {
                switch (msg.PluginMessageType)
                {
                    case PluginMessageType.Print:
                        OnReceivePrintMessage(msg);
                        break;
                    case PluginMessageType.QueryState:
                        OnReceiveQueryStateMessage(msg);
                        break;
                    case PluginMessageType.AddPrintTemplate:
                        OnReceivePrintTemplate(msg);
                        break;
                    case PluginMessageType.RemovePrintTemplate:
                        OnReceivePrintTemplate(msg);
                        break;
                    case PluginMessageType.ResetPrintTemplate:
                        OnReceivePrintTemplate(msg);
                        break;
                    case PluginMessageType.CleanPrintTemplate:
                        OnReceivePrintTemplate(msg);
                        break;
                    case PluginMessageType.Reset:
                        OnReceiveResetCommand(msg);
                        break;
                    case PluginMessageType.SendOtherCommand:
                        OnReceiveSendOtherCommand(msg);
                        break;
                    default:
                        break;
                }
            }
            
        }

        protected virtual void HandOnReceivedNativeMessage(BaseAsyncMessageHandleArgs<PluginRequestMessage> args)
        {
            if (args != null && args.Msg!=null)
            {
                HandMessage(args.Msg);
            }
        }

        protected virtual void HandOnReceivedSocketMessage(AsyncMessageHandleArgs<PluginRequestMessage> args)
        {
            if (args != null)
            {
                //byte[] sendData = Encoding.UTF8.GetBytes("33" + "\r\n");
                //args.AsyncSocketConnect.AsyncSend(sendData);
                if (args.Msg != null)
                {
                    args.Msg.SourceId = args.AsyncSocketConnect.ID;
                    HandMessage(args.Msg);
                }
                
            }
        }

        /// <summary>
        /// 当收到处理消息
        /// </summary>
        /// <param name="args"></param>
        protected virtual void OnReceiveSendOtherCommand(PluginRequestMessage msg)
        {
            if (msg != null)
            {
                PrintManager.Instance.Init(msg.PrinterType);
                PrintManager.Instance.SendCommand(msg);
            }
            
        }

        /// <summary>
        /// 当收到重启消息
        /// </summary>
        /// <param name="args"></param>
        protected virtual void OnReceiveResetCommand(PluginRequestMessage msg)
        {
            if (msg != null)
            {
                PrintManager.Instance.Init(msg.PrinterType);
                PrintManager.Instance.Reset(msg);
            }
            
        }

        /// <summary>
        /// 当收到打印模板命令
        /// </summary>
        /// <param name="args"></param>
        protected virtual void OnReceivePrintTemplate(PluginRequestMessage msg)
        {
            if (msg != null)
            {
                TemplateOperationMessage tom = null;
                PluginMessageType messageType = PluginMessageType.UnKnown;
                switch (msg.PluginMessageType)
                {
                    case PluginMessageType.AddPrintTemplate:
                        tom = new TemplateOperationMessage();
                        messageType = PluginMessageType.AddPrintTemplate;
                        try
                        {
                            int result = PrintTemplateManager.Instance.AddPaperTemplate(msg.MessageBody);
                            tom.Result = result;
                            if (result == 0)
                            {
                                tom.Des = "Success";
                            }
                            else if (result == 1)
                            {
                                tom.Des = "Exieted";
                            }
                        }
                        catch (ArgumentException ex)
                        {
                            tom.Result = -1;
                            tom.Des = "ErrorData";
                        }

                        break;
                    case PluginMessageType.RemovePrintTemplate:
                        tom = new TemplateOperationMessage();
                        messageType = PluginMessageType.RemovePrintTemplate;
                        var remove_result = PrintTemplateManager.Instance.RemovePrintTemplate(msg.MessageBody);
                        tom.Result = remove_result;
                        if (remove_result == 0)
                        {
                            tom.Des = "Success";
                        }
                        else
                        {
                            tom.Des = "Failed";
                        }
                        break;
                    case PluginMessageType.ResetPrintTemplate:
                        tom = new TemplateOperationMessage();
                        messageType = PluginMessageType.ResetPrintTemplate;
                        try
                        {
                            PrintTemplateManager.Instance.ResetPaperTemplate(msg.MessageBody);
                            tom.Result = 0;
                            tom.Des = "Success";
                        }
                        catch
                        {
                            tom.Result = -1;
                            tom.Des = "ErrorData";
                        }

                        break;
                    case PluginMessageType.CleanPrintTemplate:
                        tom = new TemplateOperationMessage();
                        messageType = PluginMessageType.CleanPrintTemplate;
                        PrintTemplateManager.Instance.Clean();
                        tom.Des = "Success";
                        tom.Result = 0;
                        break;
                }
                if (tom != null)
                {
                    CommandCompleteHander(this, messageType,
                            msg.SourceId, JsonConvert.SerializeObject(tom));
                }

            }
                        
        }

        /// <summary>
        /// 查询打印机状态
        /// </summary>
        /// <param name="args"></param>
        protected virtual void OnReceiveQueryStateMessage(PluginRequestMessage msg)
        {
            if (msg != null)
            {
                PrintManager.Instance.Init(msg.PrinterType);
                int querstate = PrintManager.Instance.QueryState(msg);
            }
            
        }

        /// <summary>
        /// 打印
        /// </summary>
        /// <param name="args"></param>
        protected virtual void OnReceivePrintMessage(PluginRequestMessage msg)
        {
            if (msg!=null)
            {
                PrintManager.Instance.Init(msg.PrinterType);
                PrintManager.Instance.Print(msg);
            }
            
        }

        /// <summary>
        /// 当命令执行完成
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="soucrId"></param>
        /// <param name="msg"></param>
        protected virtual void CommandCompleteHander(object sender,PluginMessageType messageType, string soucrId,string msg)
        {
            if (!string.IsNullOrEmpty(soucrId))
            {
                if (!string.IsNullOrEmpty(soucrId))
                {
                    
                    try
                    {
                        var socket = _socketServer.Connects[soucrId];
                        if (socket != null)
                        {
                            PluginResponseMessage response = new PluginResponseMessage();
                            response.PluginMessageType = messageType;
                            response.MessageBody = msg;
                            var creater = socket.IRecieveArgs;
                            if (creater != null)
                            {
                                socket.AsyncSend(socket.IRecieveArgs.CreateSendMsg(JsonConvert.SerializeObject(response)));
                            }

                        }
                    }
                    catch
                    {
                        
                    }
                   
                    
                    
                }
                
            }
        }

        protected virtual void HandOnConnectedServer(AsyncSocketConnect<PluginRequestMessage> connect)
        {
            //byte[] d={1,2};
            //connect.AsyncSend(d);
        }
        
        #endregion

        #region 公共方法

        public void Start() {

            //Action action = new Action(() => {
            //    RegisterNativeMessagingHost();
            //});
            
            _socketServer.InitSocket();
            _socketServer.Listen();
            //_nativeMessageServer.RecieveArgs = new AsyncReceiveArgs();
            //_nativeMessageServer.Start();
            //action.BeginInvoke(new AsyncCallback((ar) => { }), null);
            
        }

        public void Close() {
            //_nativeMessageServer.Stop();
            _socketServer.Close();
        }

        #endregion

        #region 私有方法

        private void RegisterNativeMessagingHost()
        {
            Thread.Sleep(8000);
            string keyName = "HKEY_LOCAL_MACHINE\\Software\\Google\\Chrome\\NativeMessagingHosts\\qlrrprintservice";
            try
            {
                StreamWriter manifest = File.CreateText(options.manifest);
                manifest.Write(new JObject(
                        new JProperty("name", "QlrrPrintService"),
                        new JProperty("description", "QlrrPrint Extension"),
                        new JProperty("type", "stdio"),
                        new JProperty("path", System.Reflection.Assembly.GetEntryAssembly().Location),
                        new JProperty("allowed_origins",
                            new JArray(
                                new JValue(string.Format("chrome-extension://{0}/", _extensionid))
                                )
                            )
                    ).ToString()
                    );
                manifest.Close();
            }
            catch
            {
 
            }

            try
            {
                Microsoft.Win32.Registry.SetValue(keyName, null, "D:\\work\\project\\net\\PrintServices\\printservice\\bin\\Debug\\QlrrPrintService.manifest.json");

            }
            catch (Exception ex)
            {

            }
          
        }

        #endregion

        #region IDisposeable

        public void Dispose()
        {
            throw new NotImplementedException();
        }

        #endregion
    }
}
